package com.rainbow.support.half.message.handler.consumer;

import com.rainbow.common.core.toolkit.ContextHolder;
import com.rainbow.common.core.toolkit.SpringBeanUtil;
import com.rainbow.support.half.message.entity.HalfMessagePayload;
import com.rainbow.support.half.message.handler.BaseHalfMsgHandler;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.lang.NonNull;

import java.util.Date;
import java.util.Objects;

/**
 * rocketMq半事务统一处理
 * 消费者统一处理接口规范
 * @author 傅为地
 */
public interface HalfMsgConsumerHandler extends BaseHalfMsgHandler {


    /**
     * Mq消费者,本地业务逻辑和事务日志处理
     * 不推荐采用此方法处理消费者,消息体内日期格式可能存在问题
     * 推荐采用{@link #process(HalfMessagePayload producer)}
     * @param msg 消息主体
     * @return 业务处理结果
     */
    @Deprecated
    boolean process(@NonNull String msg);


    /**
     * Mq消费者,本地业务逻辑和事务日志处理
     *
     * @param msg 消息主体
     * @return 业务处理结果
     */
    boolean process(@NonNull HalfMessagePayload msg);


    /**
     * TODO 消费者业务处理之前准备参数,需要业务自己实现
     * 本地业务逻辑处理之前,需要查询好需要处理的参数信息
     * 本地事务处理时,直接处理业务逻辑,解决大事务的问题
     *
     * @param producer 生产者参数
     */
    default void prepareParams(@NonNull HalfMessagePayload producer) {
    }


    /**
     * 本地业务处理,开启事务处理
     *
     * @param producer 生产者参数
     * @param message  消费者消息
     * @return 本地事务处理结果
     */
    boolean serviceProcess(@NonNull HalfMessagePayload producer, @NonNull String message);


    /**
     * MQ事务消费者,存储消费事务日志
     *
     * @param payload 消息载体
     * @param message 消息主体
     * @return 存储消费事务日志
     */
    default boolean saveConsumerLog(@NonNull HalfMessagePayload payload, @NonNull String message) {
        String consumerUserId=Objects.requireNonNullElse(payload.getCreator(),ContextHolder.getUserId());
        Date consumerTime=Objects.requireNonNullElse(payload.getCreateTime(),new Date());
        String insertSql = "INSERT INTO rocket_mq_consumer_log(branch_id,global_id,origin_body,create_time,creator,logic_delete) VALUES (?,?,?,?,?,?)";
        int total = Objects.requireNonNull(SpringBeanUtil.getBean(JdbcTemplate.class)).update(insertSql, payload.getBranchId(), payload.getGlobalId(), message, consumerTime,consumerUserId , false);
        return ObjectUtils.isNotEmpty(total) && total > 0;
    }

    /**
     * MQ事务消费者,检查消息主体分支事务id,是否已经存在
     *
     * @param branchId 消息主体分支事务id
     * @return 检查事务状态
     */
    default boolean checkBranchId(@NonNull String branchId) {
        int total = Objects.requireNonNull(SpringBeanUtil.getBean(JdbcTemplate.class)).queryForObject("select count(*) as total from rocket_mq_consumer_log  where logic_delete=false and branch_id = '" + branchId + "'", Integer.class);
        return ObjectUtils.isNotEmpty(total) && total > 0;
    }

}
